package com.example.havi.adapter;

import android.content.Context;
import android.graphics.drawable.AnimationDrawable;
import android.os.Bundle;
import android.support.annotation.NonNull;
import android.support.v7.widget.RecyclerView;
import android.text.Spannable;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.TextView;

import com.bumptech.glide.Glide;
import com.example.havi.R;
import com.example.havi.bean.CardBean;
import com.example.havi.bean.MessageBean;
import com.example.havi.helper.EaseChatRowVoicePlayer;
import com.example.havi.helper.GlideHelper;
import com.example.havi.helper.MessageTypes;
import com.example.havi.ui.EaseAlertDialog;
import com.example.havi.ui.chatitem.BaseChatViewHolder;
import com.example.havi.ui.chatitem.CardViewHolder;
import com.example.havi.ui.chatitem.FileViewHolder;
import com.example.havi.ui.chatitem.ImageViewHolder;
import com.example.havi.ui.chatitem.LocationViewHolder;
import com.example.havi.ui.chatitem.TextViewHolder;
import com.example.havi.ui.chatitem.VideoViewHolder;
import com.example.havi.ui.chatitem.VoiceViewHolder;
import com.example.havi.util.GsonUtils;
import com.example.havi.util.LogUtil;
import com.hyphenate.EMCallBack;
import com.hyphenate.chat.EMClient;
import com.hyphenate.chat.EMFileMessageBody;
import com.hyphenate.chat.EMImageMessageBody;
import com.hyphenate.chat.EMMessage;
import com.hyphenate.chat.EMTextMessageBody;
import com.hyphenate.chat.EMVoiceMessageBody;
import com.hyphenate.exceptions.HyphenateException;
import com.hyphenate.util.DateUtils;
import com.hyphenate.util.EMLog;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;

public class ChatMessageAdapter extends RecyclerView.Adapter<BaseChatViewHolder> {

    private List<EMMessage> allData = new ArrayList<>();
    private Context context;

    public ChatMessageAdapter(Context context) {
        this.context = context;
    }

    public List<EMMessage> getAllData() {
        return allData;
    }

    public void updateData(List<EMMessage> list) {
        allData.clear();
        allData.addAll(list);
        notifyDataSetChanged();
    }

    public void addData(List<EMMessage> list) {
        allData.addAll(0, list);
        notifyDataSetChanged();
    }

    /**
     * -------------------------------------------------1.ViewType handle start------------------------------------------------------------
     */
    @NonNull
    @Override
    public BaseChatViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
        return createItemViewHolder(parent, viewType);
    }

    private BaseChatViewHolder createItemViewHolder(ViewGroup parent, int viewType) {
        BaseChatViewHolder viewHolder = null;
        switch (viewType) {
            case MessageTypes.CARD_SEND:    //名片类型
                viewHolder = new CardViewHolder(LayoutInflater.from(context).inflate(R.layout.item_card_send, parent, false));
                break;
            case MessageTypes.CARD_RECEIVE:    //名片类型
                viewHolder = new CardViewHolder(LayoutInflater.from(context).inflate(R.layout.item_card_receive, parent, false));
                break;
            case MessageTypes.TXT_RECEIVE:
                viewHolder = new TextViewHolder(LayoutInflater.from(context).inflate(R.layout.item_txt_receive, parent, false));
                break;
            case MessageTypes.TXT_SEND:
                viewHolder = new TextViewHolder(LayoutInflater.from(context).inflate(R.layout.item_txt_send, parent, false));
                break;
            case MessageTypes.IMAGE_RECEIVE:
                viewHolder = new ImageViewHolder(LayoutInflater.from(context).inflate(R.layout.item_image_receive, parent, false));
                break;
            case MessageTypes.IMAGE_SEND:
                viewHolder = new ImageViewHolder(LayoutInflater.from(context).inflate(R.layout.item_image_send, parent, false));
                break;
            case MessageTypes.VOICE_RECEIVE:
                viewHolder = new VoiceViewHolder(LayoutInflater.from(context).inflate(R.layout.item_voice_receive, parent, false));
                break;
            case MessageTypes.VOICE_SEND:
                viewHolder = new VoiceViewHolder(LayoutInflater.from(context).inflate(R.layout.item_voice_send, parent, false));
                break;
            case MessageTypes.VIDEO_RECEIVE:
                viewHolder = new VideoViewHolder(LayoutInflater.from(context).inflate(R.layout.item_video_receive, parent, false));
                break;
            case MessageTypes.VIDEO_SEND:
                viewHolder = new VideoViewHolder(LayoutInflater.from(context).inflate(R.layout.item_video_send, parent, false));
                break;
            case MessageTypes.FILE_RECEIVE:
                viewHolder = new FileViewHolder(LayoutInflater.from(context).inflate(R.layout.item_file_receive, parent, false));
                break;
            case MessageTypes.FILE_SEND:
                viewHolder = new FileViewHolder(LayoutInflater.from(context).inflate(R.layout.item_file_send, parent, false));
                break;
            case MessageTypes.LOCATION_RECEIVE:
                viewHolder = new LocationViewHolder(LayoutInflater.from(context).inflate(R.layout.item_location_receive, parent, false));
                break;
            case MessageTypes.LOCATION_SEND:
                viewHolder = new LocationViewHolder(LayoutInflater.from(context).inflate(R.layout.item_location_send, parent, false));
                break;
        }
        return viewHolder;
    }

    @Override
    public int getItemViewType(int position) {
        int messageType = MessageTypes.TXT_RECEIVE; //默认
        EMMessage message = allData.get(position);
        //处理消息类型
        //基本信息 头像等信息 通过键值对传输
        Map<String, Object> map = message.ext();
        MessageBean messageBean = MessageBean.mapToBean(map);
        switch (messageBean.getCustomMessageType()) {
            case MessageTypes.BASIC_MESSAGE:   //环信基础类型
                messageType = getBasicMessageType(messageType, message);
                break;
            case MessageTypes.CARD_MESSAGE:     //自定义名片类型
                messageType = message.direct() == EMMessage.Direct.RECEIVE ? MessageTypes.CARD_RECEIVE : MessageTypes.CARD_SEND;
                break;
        }

        return messageType;
    }

    private int getBasicMessageType(int messageType, EMMessage message) {
        switch (message.getType()) {
            case TXT:
                messageType = message.direct() == EMMessage.Direct.RECEIVE ? MessageTypes.TXT_RECEIVE : MessageTypes.TXT_SEND;
                break;
            case IMAGE:
                messageType = message.direct() == EMMessage.Direct.RECEIVE ? MessageTypes.IMAGE_RECEIVE : MessageTypes.IMAGE_SEND;
                break;
            case VOICE:
                messageType = message.direct() == EMMessage.Direct.RECEIVE ? MessageTypes.VOICE_RECEIVE : MessageTypes.VOICE_SEND;
                break;
            case VIDEO:
                messageType = message.direct() == EMMessage.Direct.RECEIVE ? MessageTypes.VIDEO_RECEIVE : MessageTypes.VIDEO_SEND;
                break;
            case LOCATION:
                messageType = message.direct() == EMMessage.Direct.RECEIVE ? MessageTypes.LOCATION_RECEIVE : MessageTypes.LOCATION_SEND;
                break;
            case FILE:
                messageType = message.direct() == EMMessage.Direct.RECEIVE ? MessageTypes.FILE_RECEIVE : MessageTypes.FILE_SEND;
                break;
        }
        return messageType;
    }

    @Override
    public int getItemCount() {
        return allData.size();
    }


    /**
     * -------------------------------------------------2.ViewData bundle handle start------------------------------------------------------------
     */
    @Override
    public void onBindViewHolder(@NonNull BaseChatViewHolder holder, int position) {
        EMMessage emMessage = allData.get(position);
        //显示基本信息
        setUpBaseView(holder, position, emMessage);
        //消息状态
        updateMessageStatus(holder, emMessage, position);
        //消息内容
        setUpMessageContent(holder, emMessage, position);
        //点击监听
        setUpClickListener(holder, emMessage, position);
    }

    //点击监听
    private void setUpClickListener(final BaseChatViewHolder holder, final EMMessage message, final int position) {
        holder.bubbleLayout.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {   //气泡点击
                listener.onItemViewClick(holder, v, 0, position, message);
            }
        });
        holder.userAvatarView.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {//头像点击
                listener.onItemViewClick(holder, v, 1, position, message);
            }
        });
        if (message.direct() == EMMessage.Direct.SEND) {
            holder.statusView.setOnClickListener(new View.OnClickListener() {
                @Override
                public void onClick(View v) {//发送状态点击
                    listener.onItemViewClick(holder, v, 2, position, message);
                }
            });
        }
    }

    //消息内容更新
    private void setUpMessageContent(@NonNull BaseChatViewHolder holder, EMMessage message, int position) {
        Map<String, Object> map = message.ext();
        MessageBean messageBean = MessageBean.mapToBean(map);
        switch (messageBean.getCustomMessageType()) {
            case MessageTypes.BASIC_MESSAGE:   //环信基础类型
                setUpBasicMessageContent(holder, message);
                break;
            case MessageTypes.CARD_MESSAGE:     //自定义名片类型
                EMTextMessageBody txtBody = (EMTextMessageBody) message.getBody();
                CardViewHolder cardViewHolder = (CardViewHolder) holder;
                CardBean cardBean = GsonUtils.jsonToBean(txtBody.getMessage(), CardBean.class);
                cardViewHolder.card_name_tv.setText(cardBean.getNickName());
                GlideHelper.INSTANCE.loadImage(cardViewHolder.card_avatar_iv,cardBean.getAvatar());
                cardViewHolder.card_company_tv.setText(cardBean.getCompany()+" "+cardBean.getJob());
                break;
        }

    }

    private void setUpBasicMessageContent(@NonNull BaseChatViewHolder holder, EMMessage message) {
        switch (message.getType()) {
            case TXT:
                EMTextMessageBody txtBody = (EMTextMessageBody) message.getBody();
                // 设置内容
                ((TextViewHolder) holder).contentView.setText(txtBody.getMessage());
                break;
            case IMAGE:
                loadImage(holder, message);
                break;
            case VOICE:
                loadVoice(holder, message);
                break;
            case VIDEO:
                break;
            case LOCATION:
                break;
            case FILE:
                break;
        }
    }

    private void loadVoice(BaseChatViewHolder holder, EMMessage message) {
        VoiceViewHolder voiceViewHolder = (VoiceViewHolder) holder;
        EMVoiceMessageBody voiceBody = (EMVoiceMessageBody) message.getBody();
        int len = voiceBody.getLength();
        if (len > 0) {
            voiceViewHolder.voiceLengthView.setText(voiceBody.getLength() + "\"");
            voiceViewHolder.voiceLengthView.setVisibility(View.VISIBLE);
        } else {
            voiceViewHolder.voiceLengthView.setVisibility(View.INVISIBLE);
        }
        if (message.direct() == EMMessage.Direct.RECEIVE) {
            voiceViewHolder.voiceImageView.setImageResource(R.drawable.ease_chatfrom_voice_playing);
            if (message.isListened()) {
                // hide the unread icon
                voiceViewHolder.readStatusView.setVisibility(View.INVISIBLE);
            } else {
                voiceViewHolder.readStatusView.setVisibility(View.VISIBLE);
            }
            if (voiceBody.downloadStatus() == EMFileMessageBody.EMDownloadStatus.DOWNLOADING ||
                    voiceBody.downloadStatus() == EMFileMessageBody.EMDownloadStatus.PENDING) {
                if (EMClient.getInstance().getOptions().getAutodownloadThumbnail()) {
                    voiceViewHolder.progressBar.setVisibility(View.VISIBLE);
                } else {
                    voiceViewHolder.progressBar.setVisibility(View.INVISIBLE);
                }

            } else {
                voiceViewHolder.progressBar.setVisibility(View.INVISIBLE);
            }
        } else {
            if (voiceBody.downloadStatus() == EMFileMessageBody.EMDownloadStatus.DOWNLOADING ||
                    voiceBody.downloadStatus() == EMFileMessageBody.EMDownloadStatus.PENDING) {
                voiceViewHolder.progressBar.setVisibility(View.VISIBLE);
            } else {
                voiceViewHolder.progressBar.setVisibility(View.INVISIBLE);
            }
            voiceViewHolder.voiceImageView.setImageResource(R.drawable.ease_chatto_voice_playing);
        }
        // To avoid the item is recycled by listview and slide to this item again but the animation is stopped.
        EaseChatRowVoicePlayer voicePlayer = EaseChatRowVoicePlayer.getInstance(context);
        if (voicePlayer.isPlaying() && message.getMsgId().equals(voicePlayer.getCurrentPlayingId())) {
            startVoicePlayAnimation(voiceViewHolder, message);
        } else {
            stopVoicePlayAnimation(voiceViewHolder, message);
        }
    }

    AnimationDrawable voiceAnimation;

    public void startVoicePlayAnimation(VoiceViewHolder voiceViewHolder, EMMessage message) {
        if (message.direct() == EMMessage.Direct.RECEIVE) {
            voiceViewHolder.voiceImageView.setImageResource(R.drawable.voice_from_icon);
        } else {
            voiceViewHolder.voiceImageView.setImageResource(R.drawable.voice_to_icon);
        }
        voiceAnimation = (AnimationDrawable) voiceViewHolder.voiceImageView.getDrawable();
        voiceAnimation.start();

        // Hide the voice item not listened status view.
        if (message.direct() == EMMessage.Direct.RECEIVE) {
            voiceViewHolder.readStatusView.setVisibility(View.INVISIBLE);
        }
    }

    public void stopVoicePlayAnimation(VoiceViewHolder voiceViewHolder, EMMessage message) {
        if (voiceAnimation != null) {
            voiceAnimation.stop();
            //停止播放后置空
            voiceAnimation = null;
        }
        if (message.direct() == EMMessage.Direct.RECEIVE) {
            voiceViewHolder.voiceImageView.setImageResource(R.drawable.ease_chatfrom_voice_playing);
        } else {
            voiceViewHolder.voiceImageView.setImageResource(R.drawable.ease_chatto_voice_playing);
        }
    }


    private void loadImage(BaseChatViewHolder holder, EMMessage message) {
        ImageViewHolder imageHolder = (ImageViewHolder) holder;
        EMImageMessageBody body = (EMImageMessageBody) message.getBody();
        imageHolder.progressBar.setVisibility(View.GONE);
        imageHolder.percentageView.setVisibility(View.GONE);
        if (message.direct() == EMMessage.Direct.SEND) {
            GlideHelper.INSTANCE.loadImage(((ImageViewHolder) holder).imageView, body.getLocalUrl(), 500, 500);
        } else {
            GlideHelper.INSTANCE.loadImage(((ImageViewHolder) holder).imageView, body.getRemoteUrl(), 500, 500);
        }
    }

    //消息状态更新
    private void updateMessageStatus(BaseChatViewHolder holder, EMMessage emMessage, int position) {
        if (emMessage.direct() == EMMessage.Direct.SEND) {
            switch (emMessage.status()) {
                case CREATE:
                    onMessageCreate(holder);
                    break;
                case SUCCESS:
                    onMessageSuccess(holder);
                    break;
                case FAIL:
                    onMessageError(holder);
                    break;
                case INPROGRESS:
                    onMessageInProgress(holder);
                    break;
            }
        } else if (emMessage.direct() == EMMessage.Direct.RECEIVE) {
            if (!emMessage.isAcked() && emMessage.getChatType() == EMMessage.ChatType.Chat) {
                try {
                    //设置消息已读
                    EMClient.getInstance().chatManager().ackMessageRead(emMessage.getFrom(), emMessage.getMsgId());
                } catch (HyphenateException e) {
                    e.printStackTrace();
                }
            }
        }

    }

    private void onMessageCreate(BaseChatViewHolder holder) {
        holder.progressBar.setVisibility(View.VISIBLE);
        holder.statusView.setVisibility(View.GONE);
    }

    private void onMessageSuccess(BaseChatViewHolder holder) {
        holder.progressBar.setVisibility(View.GONE);
        holder.statusView.setVisibility(View.GONE);
    }

    private void onMessageError(BaseChatViewHolder holder) {
        holder.progressBar.setVisibility(View.GONE);
        holder.statusView.setVisibility(View.VISIBLE);
    }

    private void onMessageInProgress(BaseChatViewHolder holder) {
        holder.progressBar.setVisibility(View.VISIBLE);
        holder.statusView.setVisibility(View.GONE);
    }

    //显示基本信息
    private void setUpBaseView(@NonNull BaseChatViewHolder holder, int position, EMMessage emMessage) {
        if (emMessage.direct() == EMMessage.Direct.SEND) {
            if (EMClient.getInstance().getOptions().getRequireDeliveryAck()) {
                if (emMessage.isDelivered()) {
                    holder.deliveredView.setVisibility(View.VISIBLE);
                } else {
                    holder.deliveredView.setVisibility(View.INVISIBLE);
                }
            }
            if (EMClient.getInstance().getOptions().getRequireAck()) {
                if (emMessage.isAcked()) {
                    if (holder.deliveredView != null) {
                        holder.deliveredView.setVisibility(View.INVISIBLE);
                    }
                    holder.ackedView.setVisibility(View.VISIBLE);
                } else {
                    holder.ackedView.setVisibility(View.INVISIBLE);
                }
            }
        }

        //时间
        if (position == 0) {
            holder.timeStampView.setText(DateUtils.getTimestampString(new Date(emMessage.getMsgTime())));
            holder.timeStampView.setVisibility(View.VISIBLE);
        } else {
            // show time stamp if interval with last message is > 30 seconds
            EMMessage prevMessage = (EMMessage) allData.get(position - 1);
            if (prevMessage != null && DateUtils.isCloseEnough(emMessage.getMsgTime(), prevMessage.getMsgTime())) {
                holder.timeStampView.setVisibility(View.GONE);
            } else {
                holder.timeStampView.setText(DateUtils.getTimestampString(new Date(emMessage.getMsgTime())));
                holder.timeStampView.setVisibility(View.VISIBLE);
            }
        }
        //基本信息 头像等信息 通过键值对传递
        Map<String, Object> map = emMessage.ext();
        MessageBean messageBean = MessageBean.mapToBean(map);
        GlideHelper.INSTANCE.loadCircleImage(holder.userAvatarView, messageBean.getAvatar());
        if (emMessage.getChatType() == EMMessage.ChatType.GroupChat || emMessage.getChatType() == EMMessage.ChatType.ChatRoom) {
            // 群聊或者聊天室 显示昵称
            if (holder.usernickView != null) {
                holder.usernickView.setVisibility(View.VISIBLE);
                holder.usernickView.setText(messageBean.getNickName());
            }
        } else {
            //个人聊天 不显示昵称
            holder.usernickView.setVisibility(View.GONE);
        }

    }


    /**
     * -------------------------------------------------3.ViewItem click listener start------------------------------------------------------------
     */
    OnItemViewClickListener listener;

    public void setOnItemViewClickListener(OnItemViewClickListener l) {
        listener = l;
    }

    public interface OnItemViewClickListener {
        void onItemViewClick(BaseChatViewHolder holder, View view, int ViewType, int position, EMMessage emMessage);
    }
}
